home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / net / unix / tcpip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-12  |  8.7 KB  |  387 lines

  1. #include "tcpip.hpp"
  2. #include <ctype.h>
  3.  
  4. tcpip_protocol tcpip;
  5.  
  6. /*
  7. FILE *log_file=NULL;
  8. extern int net_start();
  9. void net_log(char *st, void *buf, long size)
  10. {
  11.     
  12.   if (!log_file) 
  13.   {
  14.     if (net_start())
  15.       log_file=fopen("client.log","wb");
  16.     else
  17.       log_file=fopen("server.log","wb");
  18.   }
  19.  
  20.  
  21.     fprintf(log_file,"%s%d - ",st,size);
  22.     int i;
  23.     for (i=0;i<size;i++) 
  24.       if (isprint(*((unsigned char *)buf+i)))
  25.         fprintf(log_file,"%c",*((unsigned char *)buf+i));
  26.       else fprintf(log_file,"~");
  27.  
  28.     fprintf(log_file," : ");
  29.  
  30.     for (i=0;i<size;i++) 
  31.     fprintf(log_file,"%02x, ",*((unsigned char *)buf+i),*((unsigned char *)buf+i));
  32.     fprintf(log_file,"\n");
  33.     fflush(log_file);
  34.  
  35. } */
  36.  
  37.  
  38. int unix_fd::read(void *buf, int size, net_address **addr) 
  39. {
  40.   int tr=::read(fd,buf,size);
  41.   if (addr) *addr=NULL;
  42.   return tr;
  43. }
  44.  
  45. int unix_fd::write(void *buf, int size, net_address *addr)
  46.   if (addr) fprintf(stderr,"Cannot change address for this socket type\n");
  47.   return ::write(fd,buf,size); 
  48. }
  49.  
  50.  
  51. net_address *tcpip_protocol::get_local_address()
  52. {
  53.   char my_name[100];                              // now check to see if this address is 'hostname'
  54.   gethostname(my_name,100);
  55.   struct hostent *l_hn=gethostbyname(my_name);  
  56.   ip_address *a=new ip_address();
  57.   memset(&a->addr,0,sizeof(a->addr));
  58.   memcpy(&a->addr.sin_addr,*l_hn->h_addr_list,4);  
  59. }
  60.  
  61. net_address *tcpip_protocol::get_node_address(char *&server_name, int def_port, int force_port)
  62. {
  63.   char name[256],*np;
  64.   np=name;
  65.   while (*server_name && *server_name!=':' && *server_name!='/')
  66.     *(np++)=*(server_name)++;
  67.   *np=0;
  68.   if (*server_name==':')
  69.   {
  70.     server_name++;
  71.     char port[256],*p;
  72.     p=port;
  73.     while (*server_name && *server_name!='/')
  74.       *(p++)=*(server_name++);
  75.     *p=0;
  76.     int x;
  77.     if (!force_port)
  78.     {
  79.       if (sscanf(port,"%d",&x)==1) def_port=x;
  80.       else return 0;
  81.     }
  82.   }
  83.  
  84.   if (*server_name=='/') server_name++;
  85.  
  86.   hostent *hp=gethostbyname(name);
  87.   if (!hp)
  88.   { 
  89.     fprintf(stderr,"unable to locate server named '%s'\n",name);
  90.     return 0;
  91.   }
  92.   
  93.  
  94.   sockaddr_in host;
  95.   memset( (char*) &host,0, sizeof(host));
  96.   host.sin_family = AF_INET;
  97.   host.sin_port = htons(def_port);
  98.   host.sin_addr.s_addr = htonl(INADDR_ANY);
  99.   memcpy(&host.sin_addr,hp->h_addr,hp->h_length);
  100.   return new ip_address(&host);
  101. }
  102.  
  103. net_socket *tcpip_protocol::connect_to_server(net_address *addr, net_socket::socket_type sock_type)
  104. {
  105.   if (addr->protocol_type()!=net_address::IP)
  106.   {
  107.     fprintf(stderr,"Procotol type not supported in the executable\n");
  108.     return NULL;
  109.   }
  110.  
  111.   int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
  112.   if (socket_fd<0) 
  113.   {
  114.     fprintf(stderr,"unable to create socket (too many open files?)\n");
  115.     return 0;
  116.   }
  117.  
  118.   int zz;
  119.   if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
  120.   {
  121.     fprintf(stderr,"could not set socket option reuseaddr");
  122.     return 0;
  123.   }
  124.  
  125.     
  126.   if (connect(socket_fd, (struct sockaddr *) &((ip_address *)addr)->addr, sizeof( ((ip_address *)addr)->addr ))==-1)
  127.   { 
  128.     fprintf(stderr,"unable to connect\n");
  129.     close(socket_fd);
  130.     return 0;
  131.   }
  132.  
  133.   if (sock_type==net_socket::SOCKET_SECURE)
  134.     return new tcp_socket(socket_fd);
  135.   else
  136.     return new udp_socket(socket_fd);
  137. }
  138.  
  139.  
  140. net_socket *tcpip_protocol::create_listen_socket(int port, net_socket::socket_type sock_type, char *name)
  141. {
  142.   int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
  143.   if (socket_fd<0) 
  144.   {
  145.     fprintf(stderr,"unable to create socket (too many open files?)\n");
  146.     return 0;
  147.   }
  148. /*  int zz;
  149.   if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
  150.   {
  151.     fprintf(stderr,"could not set socket option reuseaddr");
  152.     return 0;
  153.   } */
  154.  
  155.  
  156.   net_socket *s;
  157.   if (sock_type==net_socket::SOCKET_SECURE)
  158.     s=new tcp_socket(socket_fd);
  159.   else s=new udp_socket(socket_fd);
  160.   if (s->listen(port)==0)
  161.   {   
  162.     delete s;
  163.     return 0;
  164.   }
  165.  
  166.   return s;
  167. }
  168.  
  169.  
  170. tcpip_protocol::tcpip_protocol()
  171. {
  172.   FD_ZERO(&master_set);  
  173.   FD_ZERO(&master_write_set);  
  174.   FD_ZERO(&read_set);
  175.   FD_ZERO(&exception_set);
  176.   FD_ZERO(&write_set); 
  177. }
  178.  
  179.  
  180. int tcpip_protocol::select(int block)
  181. {
  182.   memcpy(&read_set,&master_set,sizeof(master_set));
  183.   memcpy(&exception_set,&master_set,sizeof(master_set));
  184.   memcpy(&write_set,&master_write_set,sizeof(master_set));
  185.   if (block)
  186.     return ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,NULL);
  187.   else
  188.   {
  189.     timeval tv={0,0};
  190.     return ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,&tv);
  191.   }
  192. }
  193.  
  194.  
  195.  
  196. net_socket *tcpip_protocol::start_notify(int port, void *data, int len)
  197. //{{{
  198. {
  199.     if (responder)
  200.     {
  201.         delete responder;
  202.         delete bcast;
  203.         responder = 0;
  204.     }
  205.     
  206.     int resp_len = strlen(notify_response);
  207.   notify_len = len + resp_len + 1;
  208.   strcpy(notify_data,notify_response);
  209.     notify_data[resp_len] = '.';
  210.   memcpy(notify_data+resp_len+1,data,len);
  211.   
  212.   // create notifier socket
  213. #ifdef TCPIP_DEBUG
  214.     fprintf(stderr,"Creating notifier on port %d\n",port);
  215. #endif
  216.   notifier = create_listen_socket(port, net_socket::SOCKET_FAST);
  217.   
  218.   if (notifier)
  219.   {
  220.     notifier->read_selectable();
  221.     notifier->write_unselectable();
  222.   }
  223.   else
  224.         fprintf(stderr,"Couldn't start notifier\n");
  225.   
  226.   return notifier;
  227. }
  228. //}}}///////////////////////////////////
  229.  
  230.  
  231. void tcpip_protocol::end_notify()
  232. //{{{
  233. {
  234.   if (notifier)
  235.     delete notifier;
  236.   notifier = 0;
  237.  
  238.   notify_len = 0;
  239. }
  240. //}}}///////////////////////////////////
  241.  
  242. int tcpip_protocol::handle_notification()
  243. //{{{
  244. {
  245.   if (!notifier)
  246.     return 0;
  247.     
  248.   if (notifier->ready_to_read())
  249.   {
  250.     char buf[513];
  251.     int len;
  252.     // got a notification request "broadcast"
  253.     ip_address *addr;
  254.  
  255. #ifdef TCPIP_DEBUG
  256.         printf("Notifier: ");
  257. #endif
  258.  
  259.     len = notifier->read(buf, 512, (net_address**)&addr);
  260. #ifdef TCPIP_DEBUG
  261.         if (len>0) {
  262.             buf[len] = 0;
  263.             printf("[%s] ",buf);
  264.         }
  265. #endif
  266.     if (addr && len>0)
  267.     {
  268.             buf[len] = 0;
  269.       if  (strcmp(buf, notify_signature)==0) {
  270.                 char s[256];
  271. #ifdef TCPIP_DEBUG
  272.                 addr->store_string(s,256);
  273.                 printf("responding to %s",s);
  274. #endif
  275.         // send notification data to requester
  276.         notifier->write(notify_data,notify_len,addr);
  277.             }
  278.         
  279.       delete addr;
  280.     }
  281. #ifdef TCPIP_DEBUG
  282.         printf("\n");
  283. #endif
  284.     return 1;
  285.   }
  286.   if (notifier->error())
  287.   {
  288.     fprintf(stderr,"Error on notification socket!\n");
  289.     return 1;
  290.   }
  291.  
  292.   return 0;
  293. }
  294. //}}}///////////////////////////////////
  295.  
  296. net_address *tcpip_protocol::find_address(int port, char *name)
  297. //{{{
  298. {
  299.   // name should be a 256 byte buffer
  300.     char s[256];
  301.  
  302.     end_notify();
  303.  
  304.   if (!responder) {
  305. //#ifdef TCPIP_DEBUG
  306.         fprintf(stderr,"Creating responder on port %d\n",port);
  307. //#endif
  308.     responder = create_listen_socket(port, net_socket::SOCKET_FAST);
  309.         responder->read_selectable();
  310.         responder->write_unselectable();
  311.     bcast = (ip_address *)get_local_address();
  312.     bcast->set_port(port);
  313.     
  314. //#ifdef TCPIP_DEBUG
  315.         *((unsigned char *)(&bcast->addr.sin_addr)+3) = 255;
  316.         bcast->store_string(s,256);
  317.         fprintf(stderr,"Simulating broadcast to [%s]\n",s);
  318. //#endif
  319.  
  320.         *((unsigned char *)(&bcast->addr.sin_addr)+3) = 0;        
  321.     }
  322.  
  323.   if (responder)
  324.   {
  325.     int i;
  326.     
  327.     for (i=0; i<5; i++)
  328.     {
  329. #ifdef TCPIP_DEBUG
  330.             bcast->store_string(s,256);
  331.             fprintf(stderr,"\r[%s]",s);
  332. #endif
  333.         int found = 0;
  334.         
  335.         for (p_request p = servers.begin(); !found && p!=servers.end(); ++p)
  336.             if ( *((*p)->addr) == *bcast )
  337.                 found = 1;
  338.         for (p_request q = returned.begin(); !found && q!=returned.end(); ++q)
  339.             if ( *((*q)->addr) == *bcast )
  340.                 found = 1;
  341.                 
  342.             if (!found) {
  343.                 responder->write((void*)notify_signature,
  344.                                                  strlen(notify_signature),bcast);
  345.                 select(0);
  346.             }
  347.         *((unsigned char *)(&bcast->addr.sin_addr)+3) += 1;
  348.     
  349.         select(0);
  350.         
  351.         if (!servers.empty())
  352.             break;
  353.         }
  354.   }
  355.   
  356.   if (servers.empty())
  357.     return 0;
  358.  
  359.   servers.move_next(servers.begin_prev(), returned.begin_prev());
  360.     ip_address *ret = (ip_address*)(*returned.begin())->addr->copy();
  361.     strcpy(name,(*returned.begin())->name);
  362.  
  363. #ifdef TCPIP_DEBUG
  364.     ret->store_string(s,256);
  365.     fprintf(stderr,"Found [%s]\n",s);
  366. #endif
  367.  
  368.   return ret;
  369. }
  370. //}}}///////////////////////////////////
  371.  
  372. void tcpip_protocol::reset_find_list()
  373. //{{{
  374. {
  375.     p_request p;
  376.     
  377.     for (p=servers.begin(); p!=servers.end(); ++p)
  378.         delete (*p)->addr;
  379.     for (p=returned.begin(); p!=returned.end(); ++p)
  380.         delete (*p)->addr;
  381.         
  382.   servers.erase_all();
  383.   returned.erase_all();
  384. }
  385. //}}}///////////////////////////////////
  386.